﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.Storage.Pickers;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

// 사용자 정의 컨트롤 항목 템플릿에 대한 설명은 http://go.microsoft.com/fwlink/?LinkId=234236에 나와 있습니다.

namespace Hoons_Player.Yang
{
	public sealed partial class Player : UserControl
	{
		#region { 전역변수 }
		private DispatcherTimer _timer;
		private bool _sliderpressed = false;
		private double stepfrequency = -1;
		private string strStringFormat = "{0:00}:{1:00}";
		#endregion

		public Player()
		{
			this.InitializeComponent();

			this.Loaded += Player_Loaded;
		}

		void Player_Loaded(object sender, RoutedEventArgs e)
		{
			oMediaPlayer.MediaOpened += oMediaPlayer_MediaOpened;
			oMediaPlayer.MediaEnded += oMediaPlayer_MediaEnded;
			oMediaPlayer.MediaFailed += oMediaPlayer_MediaFailed;
			oMediaPlayer.CurrentStateChanged += oMediaPlayer_CurrentStateChanged;

			//For support Background Audio
			MediaControl.PlayPressed += MediaControl_PlayPressed;
			MediaControl.PausePressed += MediaControl_PausePressed;
			MediaControl.PlayPauseTogglePressed += MediaControl_PlayPauseTogglePressed;
			MediaControl.StopPressed += MediaControl_StopPressed;

			PlaySlider.ValueChanged += timelineSlider_ValueChanged;

			PointerEventHandler pointerpressedhandler = new PointerEventHandler(slider_PointerEntered);
			PlaySlider.AddHandler(Control.PointerPressedEvent, pointerpressedhandler, true);

			PointerEventHandler pointerreleasedhandler = new PointerEventHandler(slider_PointerCaptureLost);
			PlaySlider.AddHandler(Control.PointerCaptureLostEvent, pointerreleasedhandler, true);

			PlaySlider.ThumbToolTipValueConverter = new ThumbToolTipValueConverter(); //Tool Tip
		}

		#region { Background Audio Event }
		private void MediaControl_StopPressed(object sender, object e)
		{
			oMediaPlayer.Stop();
		}

		async private void MediaControl_PlayPauseTogglePressed(object sender, object e)
		{
			await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
			{
				if (oMediaPlayer.CurrentState == MediaElementState.Playing)
				{
					oMediaPlayer.Pause();
				}
				else
				{
					oMediaPlayer.Play();
				}
			});
		}

		private void MediaControl_PausePressed(object sender, object e)
		{
			oMediaPlayer.Pause();
		}

		private void MediaControl_PlayPressed(object sender, object e)
		{
			oMediaPlayer.Play();
		}
		#endregion

		#region { oMediaPlayer Event }
		void oMediaPlayer_CurrentStateChanged(object sender, RoutedEventArgs e)
		{
			if (oMediaPlayer.CurrentState == MediaElementState.Playing)
			{
				if (_sliderpressed)
				{
					_timer.Stop();
				}
				else
				{
					_timer.Start();
				}
				MediaControl.IsPlaying = true;
			}

			if (oMediaPlayer.CurrentState == MediaElementState.Paused)
			{
				_timer.Stop();
				MediaControl.IsPlaying = false;
			}

			if (oMediaPlayer.CurrentState == MediaElementState.Stopped)
			{
				_timer.Stop();
				PlaySlider.Value = 0;
				MediaControl.IsPlaying = false;
			}
		}

		void oMediaPlayer_MediaFailed(object sender, ExceptionRoutedEventArgs e)
		{
		}

		void oMediaPlayer_MediaEnded(object sender, RoutedEventArgs e)
		{
		}

		void oMediaPlayer_MediaOpened(object sender, RoutedEventArgs e)
		{
			double absvalue = (int)Math.Round(oMediaPlayer.NaturalDuration.TimeSpan.TotalSeconds, MidpointRounding.AwayFromZero);
			PlaySlider.Maximum = absvalue;
			PlaySlider.StepFrequency = stepfrequency;
			tb_StartTime.Text = string.Format(strStringFormat, 0, 0);
			tb_EndTime.Text = string.Format(strStringFormat, Math.Floor(absvalue / 60), Math.Floor(absvalue % 60));
			SetTimer();
		}
		#endregion

		#region { Display Button Event }
		async private void btn_Open_Tapped(object sender, TappedRoutedEventArgs e)
		{
			try
			{
				StorageFile oFile;
				FileOpenPicker picker = new FileOpenPicker();
				picker.FileTypeFilter.Add(".mp3");
				oFile = await picker.PickSingleFileAsync();
				oMediaPlayer.SetSource((await oFile.OpenAsync(FileAccessMode.Read)), "mp3");

				MusicProperties oMP;
				oMP = await oFile.Properties.GetMusicPropertiesAsync();
				tb_Song.Text = oMP.Title;
				tb_Artist.Text = oMP.Artist;
				tb_Album.Text = oMP.Album;
				TimeSpan oTimeSpan = oMP.Duration;
				string strEndTime = string.Format("{0}:{1}", oTimeSpan.Minutes, oTimeSpan.Seconds);
				tb_EndTime.Text = strEndTime;
				tb_StartTime.Text = "00:00";
				//Image
				StorageItemThumbnail oST = await oFile.GetThumbnailAsync(ThumbnailMode.MusicView);
				BitmapImage bi = new BitmapImage();
				bi.UriSource = MediaControl.AlbumArt;
				bi.SetSource(oST);
				AlbumArtImage.Source = bi;
			}
			catch (Exception ex)
			{
				//var md = new MessageDialog(ex.ToString());
				//md.ShowAsync();
			}
		}

		private void btn_Previous_Tapped(object sender, TappedRoutedEventArgs e)
		{
		}

		private void btn_Play_Tapped(object sender, TappedRoutedEventArgs e)
		{
			oMediaPlayer.Play();
		}
		private void btn_Pause_Tapped(object sender, TappedRoutedEventArgs e)
		{
			oMediaPlayer.Pause();
		}
		private void btn_Stop_Tapped(object sender, TappedRoutedEventArgs e)
		{
			oMediaPlayer.Stop();
		}
		private void btn_Next_Tapped(object sender, TappedRoutedEventArgs e)
		{
		}
		#endregion

		#region { timer }
		void slider_PointerEntered(object sender, PointerRoutedEventArgs e)
		{
			//System.Diagnostics.Debug.WriteLine("Pointer entered event fired");
			_sliderpressed = true;
		}

		void slider_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
		{
			//System.Diagnostics.Debug.WriteLine("Pointer capture lost event fired");
			//System.Diagnostics.Debug.WriteLine("Slider value at capture lost {0}", PlaySlider.Value);
			//myMediaElement.PlaybackRate = 1;
			oMediaPlayer.Position = TimeSpan.FromSeconds(PlaySlider.Value);
			_sliderpressed = false;
		}

		void timelineSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
		{
			//System.Diagnostics.Debug.WriteLine("Slider old value = {0} new value = {1}.", e.OldValue, e.NewValue);
			if (!_sliderpressed)
			{
				oMediaPlayer.Position = TimeSpan.FromSeconds(e.NewValue);
			}
		}
		#endregion

		#region { timer function }
		private void SetTimer()
		{
			_timer = new DispatcherTimer();
			_timer.Interval = TimeSpan.FromSeconds(PlaySlider.StepFrequency);
			StartTimer();
		}

		private void StartTimer()
		{
			_timer.Tick += _timer_Tick;
			_timer.Start();
		}

		private void StopTimer()
		{
			_timer.Stop();
			_timer.Tick -= _timer_Tick;
		}

		private void _timer_Tick(object sender, object e)
		{
			if (!_sliderpressed)
			{
				double dTotalSeconds = oMediaPlayer.Position.TotalSeconds;
				PlaySlider.Value = dTotalSeconds;
				tb_StartTime.Text = string.Format(strStringFormat, Math.Floor(dTotalSeconds / 60), Math.Floor(dTotalSeconds % 60));
			}
		}
		#endregion
	}

	public class ThumbToolTipValueConverter : IValueConverter
	{
		private string strStringFormat = "{0:00}:{1:00}";
		/// <summary>
		/// 
		/// </summary>
		public object Convert(object value, Type targetType, object parameter, string language)
		{
			if (value == null)
				return string.Format(strStringFormat, 0, 0);
			// ...
			double val = (double)value;
			return string.Format(strStringFormat, Math.Floor(val / 60), Math.Floor(val % 60));
		}
		/// <summary>
		/// 
		/// </summary>
		public object ConvertBack(object value, Type targetType, object parameter, string language)
		{
			throw new Exception();
		}
	}
}
